package org.teachertools.web.tag;

import java.io.IOException;
import java.util.List;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;

import org.apache.log4j.Logger;
import org.displaytag.localization.I18nJstlAdapter;
import org.displaytag.localization.I18nResourceProvider;
import org.displaytag.localization.I18nSpringAdapter;
import org.displaytag.localization.I18nStrutsAdapter;

public class MessagesTag extends TagSupport {

    private static final String DEFAULT_MESSAGES_NAME = "messages";

    private static final long serialVersionUID = 1L;

    private static final Logger logger = Logger.getLogger(MessagesTag.class);
    private static final String lineEnd = System.getProperty("line.separator");

    private I18nResourceProvider adapter;

    private String list = DEFAULT_MESSAGES_NAME;
    private String header = null;
    private String footer = null;
    private String beforeMessage = null;
    private String afterMessage = null;

    public MessagesTag() {
        super();
    }

    /**
     * Render the specified error messages if there are any.
     */
    @Override
    public int doStartTag() throws JspException {
        @SuppressWarnings("unchecked")
        List<String> messages = (List<String>) this.pageContext.findAttribute(this.list);
        if (messages == null || messages.size() == 0) {
            return EVAL_BODY_INCLUDE;
        }
        try {
            // Try Spring MVC
            Class.forName("org.springframework.context.MessageSource");
            this.adapter = new I18nStrutsAdapter();
        } catch (Throwable t) {
            try {
                // Try Struts
                Class.forName("org.apache.struts.Globals");
                this.adapter = new I18nSpringAdapter();
            } catch (Throwable th) {
                // Fallback on JSTL
                this.adapter = new I18nJstlAdapter();
            }
        }
        logger.debug("Using " + this.adapter.getClass().getName() + "message resource adapter");
        if (this.adapter != null) {
            this.header = this.adapter
                    .getResource("messages.header", "<ul class=\"messages\">", this, this.pageContext);
            this.footer = this.adapter.getResource("messages.header", "</ul>", this, this.pageContext);
            this.beforeMessage = this.adapter.getResource("messages.header", "<li class=\"message\">", this,
                    this.pageContext);
            this.afterMessage = this.adapter.getResource("messages.header", "</li>", this, this.pageContext);
        }

        // Render the error messages appropriately
        StringBuffer results = new StringBuffer();
        if (this.header != null) {
            results.append(this.header).append(lineEnd);
        }
        for (String message : messages) {
            if (this.beforeMessage != null) {
                results.append(this.beforeMessage).append(lineEnd);
            }
            results.append(this.adapter.getResource(message, message, this, this.pageContext)).append(lineEnd);
            if (this.afterMessage != null) {
                results.append(this.afterMessage).append(lineEnd);
            }
        }
        if (this.footer != null) {
            results.append(this.footer).append(lineEnd);
        }
        try {
            this.pageContext.getOut().write(results.toString());
        } catch (IOException e) {
            logger.error("Can't write tag html content", e);
        }
        return (EVAL_BODY_INCLUDE);

    }

    public String getList() {
        return this.list;
    }

    public void setList(String list) {
        this.list = list;
    }

    /**
     * Release any acquired resources.
     */
    @Override
    public void release() {
        super.release();
        this.list = DEFAULT_MESSAGES_NAME;
    }
}
